
type Number = Int
type Numbers = [Number]
type XMAS = (Numbers,Numbers)

parseInput :: Int -> String -> XMAS
parseInput preCount string = 
    (preambleNumbers, numbers)
    where
        tokens = lines string
        preambleNumbers = map read . take preCount $ tokens
        numbers = map read . drop preCount $ tokens

canTwoSum :: Numbers -> Number -> Bool
canTwoSum [] _ = False
canTwoSum [x] _ = False
canTwoSum (x:xs) target = 
    if hasReminder 
        then True
        else canTwoSum xs target
    where
        reminder = target - x
        hasReminder = elem reminder xs

firstNotSum :: XMAS -> Number
firstNotSum (preambleNumbers, []) = error "No Number"
firstNotSum (preambleNumbers@(preambleNumber:leftpreambleNumbers), n:numbers) = 
    if canTwoSum preambleNumbers n 
        then firstNotSum (leftpreambleNumbers ++ [n], numbers)
        else n

checkContiguousSum :: Numbers -> Number -> Maybe Number
checkContiguousSum numbers target 
    | null products = Nothing
    | otherwise = if lastProduct == target 
                    then Just (maximum contiguousLst + minimum contiguousLst)
                    else Nothing
    where
        products = takeWhile (<=target) . drop 2 . scanl (+) 0 $ numbers
        lastProduct = last products
        contiguousLst = take (length products + 1) numbers

getResult :: Numbers -> Number -> Number
getResult numbers@(n:ns) target = 
    case curResult of
        Just res -> res
        Nothing -> getResult ns target
    where
        curResult = checkContiguousSum numbers target

main = do
    input <- readFile "input.txt"

    let target = firstNotSum . parseInput 25 $ input

    print . getResult (map read (lines input)) $ target